package nc.bs.hrppl.pjapplication.ace.bp.rule;

import java.util.*;

import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.framework.common.NCLocator;
import nc.codeplatform.framework.commons.DaoUtils;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.itf.hrppl.jxaimstype.jxaimstype.IJXaimsTypeVOService;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.jdbc.framework.processor.MapProcessor;
import nc.pubitf.para.SysInitQuery;
import nc.vo.hrppl.pjapplication.AggPjapplVO;
import nc.vo.hrppl.pjapplication.PJApplHVO;
import nc.vo.hrppl.pjapplication.PjapplBVO;
import nc.vo.hrppl.pjapplication.PjapplCVO;
import nc.vo.hrppl.type.JXaimsTypeVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.ISuperVO;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.model.entity.bill.IBill;
import nccloud.commons.lang.StringUtils;
import org.apache.commons.lang3.ArrayUtils;

/**
 * 新增与修改相同校验保存前规则
 *
 * @author luoliuchuan by
 */
@SuppressWarnings("rawtypes")
public class AcePjapplicationDataRule implements IRule {
    public void process (Object[] bills) {
        // 起始日期小于结止日期,项目总预算大于等于当年预算
        // 可以优化为一次检查全部,一次提示
        IBill[] bs = (IBill[]) bills;
        for (IBill bill : bs) {
            ISuperVO head = bill.getParent();
            ISuperVO[] childs = bill.getChildren(nc.vo.hrppl.pjapplication.PjapplBVO.class);
            if ((childs == null) || (childs.length == 0)) {
                ExceptionUtils.wrappBusinessException("表体数据不能为空！");
            }
            //过滤掉状态为删除的表体
            childs=(ISuperVO[]) Arrays.stream(childs).filter(child->child.getStatus() != 3 ).toArray(ISuperVO[] ::new);
            List<String> strList = new ArrayList<String>();
            // StringBuilder sbd = new StringBuilder();
            // 没要求提示重复内容先不具体提醒,后续有要求可以打开 FIXME
            for (int i = 0; i < childs.length; i++) {
                PjapplBVO childVO = (PjapplBVO) childs[i];
                if (strList.contains(childVO.getCapitalsource())) {
                    // sbd.append(childVO.getr);
                    ExceptionUtils.wrappBusinessException("表体资金来源数据不能重复！");
                } else {
                    strList.add(childVO.getCapitalsource());
                }
            }
            //导入时必输项在这里校验，当绩效信息页签不为空时，做必输项字段校验
            ISuperVO[] performanceInfo = bill.getChildren(nc.vo.hrppl.pjapplication.PjapplCVO.class);
            if ((performanceInfo != null) && performanceInfo.length > 0) {
                performanceInfo = (ISuperVO[]) Arrays.stream(performanceInfo).filter(child -> child.getStatus() != 3).toArray(ISuperVO[]::new);
            }
            if ((performanceInfo != null) && performanceInfo.length > 0) {
                //校验指标名称是否重复
                HashSet<String> jxaims = new HashSet<String>();
                int length = performanceInfo.length;
                for (int i = 0; i < performanceInfo.length; i++) {
                    PjapplCVO childVO = (PjapplCVO) performanceInfo[i];
                    if (StringUtils.isBlank(childVO.getPk_jxaimstypev1())) {
                        ExceptionUtils.wrappBusinessException("绩效信息页签一级指标不能为空！");
                    }
                    if(StringUtils.isBlank(childVO.getPk_jxaims())){
                        ExceptionUtils.wrappBusinessException("绩效信息页签指标名称不能为空！");
                    }
                    //校验指标名称是否重复
                    if (childVO.getStatus() != 3){
                        jxaims.add(childVO.getPk_jxaims());
                    }else{
                        length--;
                    }
                }

                if (jxaims.size() != length) {
                    ExceptionUtils.wrappBusinessException("绩效信息页签指标名称不能重复！");
                }
            }


//			UFDate startingdate = (UFDate) head.getAttributeValue("startingdate");
//			UFDate closingdate = (UFDate) head.getAttributeValue("closingdate");
//			if (startingdate.after(closingdate) || startingdate.isSameDate(closingdate)) {
//				ExceptionUtils.wrappBusinessException("起始日期必须小于截止日期");
//			}

            // 如果是<淘汰库>修改,保存后应该是草稿库
            // 判断状态是否改变
            int pjlibcategory = (int) head.getAttributeValue("pjlibcategory");
            if (pjlibcategory == 5) {
                ((AggPjapplVO) bill).getParentVO().setPjlibcategory(1);
            }
//			String applyear=(String) head.getAttributeValue("applyyear");
//			try{
//			int year=Integer.valueOf(applyear);
//			if(year>1000&&year<3000){
//
//			}else{
//				ExceptionUtils.wrappBusinessException("申请年度不是有效的年度");
//			}
//			}catch (Exception e){
//				ExceptionUtils.wrappBusinessException("申请年度不是有效的整数");
//			}

            //根据参数HRPXM006校验父项目的总金额要大于等于所有子项目的总金额
            PJApplHVO headvo = (PJApplHVO) bill.getParent();
            UFBoolean HRPXM006_Boolean;
            String errorMsg="";
            try {
                HRPXM006_Boolean = SysInitQuery.getParaBoolean(headvo.getPk_group(), "HRPXM006");
                if (HRPXM006_Boolean.booleanValue()) {
                    if (StringUtils.isNotEmpty(headvo.getBelongpro())) {

                        UFDouble father_data = UFDouble.ZERO_DBL;
                        Object father = new DaoUtils().getBaseDAO().executeQuery(" SELECT PJTOTALCOST FROM HRPPL_PJAPPL WHERE  PK_PJAPPL = '"+headvo.getBelongpro()+"' ",new ColumnProcessor());
                        if (father != null) {
                            father_data = new UFDouble(String.valueOf(father));

                            UFDouble total_data = UFDouble.ZERO_DBL;
                            Object total = new DaoUtils().getBaseDAO().executeQuery(" SELECT SUM(PJTOTALCOST) total FROM HRPPL_PJAPPL WHERE BELONGPRO = '"
                                    + headvo.getBelongpro() + "' AND PK_PJAPPL != '"+headvo.getPrimaryKey()+"' ", new ColumnProcessor());
                            if (total != null) {
                                total_data = new UFDouble(String.valueOf(total));
                            }
                            UFDouble result = headvo.getPjtotalcost().add(total_data).sub(father_data);
                            if (result.doubleValue() > 0) {
                                errorMsg="当前单据父项目的所有子项目经费总和已超过父项目总经费:"+new UFDouble(result.doubleValue(),2)+"元";
                            }
                        }
                    }
                }
            } catch (BusinessException e) {
                ExceptionUtils.wrappBusinessException("当前单据父项目的所有子项目经费总和是否超过父项目总经费时异常");

            }
            if(StringUtils.isNotBlank(errorMsg)) {
                ExceptionUtils.wrappBusinessException(errorMsg);
            }

            for (Object cbill : bills) {
                UFDouble score = UFDouble.ZERO_DBL;
                PjapplCVO[] bvos = (PjapplCVO[]) ((AggPjapplVO) cbill).getChildren(PjapplCVO.class);
                //绩效信息数组过滤状态为3的信息
                if ((bvos != null) && bvos.length > 0) {
                    bvos = Arrays.stream(bvos).filter(cchild -> cchild.getStatus() != 3).toArray(PjapplCVO[]::new);
                }
                if(ArrayUtils.isEmpty(bvos))
                    continue;
                if (Objects.nonNull(bvos) && bvos.length>0){
                    for (PjapplCVO bvo: bvos) {
                        score = score.add(Objects.nonNull(bvo.getDim88()) ? bvo.getDim88() : UFDouble.ZERO_DBL);
                    }
                }
                if (score.compareTo(new UFDouble(90))!=0){
                    ExceptionUtils.wrappBusinessException("绩效评分占比合计必须等于90!\r");
                }
            }
            for (Object cbill : bills) {
                Map<String, UFDouble> resultMap = new HashMap<>();
                PjapplCVO[] bvos = (PjapplCVO[]) ((AggPjapplVO) cbill).getChildren(PjapplCVO.class);
                //绩效信息数组过滤状态为3的信息
                if ((bvos != null) && bvos.length > 0) {
                    bvos = Arrays.stream(bvos).filter(cchild -> cchild.getStatus() != 3).toArray(PjapplCVO[]::new);
                }
                if (Objects.nonNull(bvos) && bvos.length>0){
                    for (PjapplCVO bvo: bvos) {
                        if (resultMap.containsKey(bvo.getPk_jxaimstypev1())) {
                            resultMap.put(bvo.getPk_jxaimstypev1(), resultMap.get(bvo.getPk_jxaimstypev1()).add(Objects.nonNull(bvo.getDim88()) ? bvo.getDim88() : UFDouble.ZERO_DBL));
                        }
                        else {
                            resultMap.put(bvo.getPk_jxaimstypev1(), Objects.nonNull(bvo.getOppvalue()) ? bvo.getDim88() : UFDouble.ZERO_DBL);
                        }
                    }
                }
                if (!resultMap.isEmpty()) {
                    for (Map.Entry<String, UFDouble> entry : resultMap.entrySet()) {
                        String key = entry.getKey();
                        UFDouble value = entry.getValue();
                        IJXaimsTypeVOService service = NCLocator.getInstance().lookup(IJXaimsTypeVOService.class);
                        JXaimsTypeVO vo = null;
                        try {
                            vo = service.findJXaimsTypeVOByPk(key, false);
                        } catch (BusinessException e) {
                            throw new RuntimeException(e);
                        }
                        UFDouble nratio = Objects.nonNull(vo.getNratio()) ? vo.getNratio() : UFDouble.ZERO_DBL;
                        if (nratio.compareTo(value) != 0){
                            ExceptionUtils.wrappBusinessException("相同一级大类下的绩效指标评分占比必须等于一级大类分数!\r");
                        }
                    }
                }
            }
            // modify by wangyong at 采购四级项目
            nc.vo.hrppl.pjapplication.PjapplPVO[] bvos = (nc.vo.hrppl.pjapplication.PjapplPVO[]) bill.getChildren(nc.vo.hrppl.pjapplication.PjapplPVO.class);
            if ((bvos != null) && bvos.length > 0) {
                bvos = Arrays.stream(bvos).filter(cchild -> cchild.getStatus() != 3).toArray(nc.vo.hrppl.pjapplication.PjapplPVO[]::new);
            }
            if(ArrayUtils.isEmpty(bvos))
                continue;
            if (Objects.nonNull(bvos) && bvos.length>0){
                int rowno = 10;
                Object applyyear = head.getAttributeValue("applyyear");
                Object pk_org = head.getAttributeValue("pk_org");
                Object officedept = head.getAttributeValue("officedept");
                for (nc.vo.hrppl.pjapplication.PjapplPVO bvo: bvos) {
                    bvo.setStatus(VOStatus.NEW);
                    Object vbdef1 = bvo.getAttributeValue("vbdef1");
                    Object name = bvo.getAttributeValue("name");
                    if (vbdef1 != null && name == null){
                        if(officedept == null || "".equals(officedept) || pk_org == null || "".equals(pk_org) ) {
                            ExceptionUtils.wrappBusinessException("预算年度、业务归口管理部门、业务单元 不允许为空!");
                        }
                        StringBuilder sql = new StringBuilder();
                        sql.append("SELECT *  FROM HRPBM_SJXMH  WHERE 1 = 1 ");
                        sql.append(" and pk_sjxm = '"+vbdef1+"' " );
                        sql.append(FourXMBusinessSQL.getFourXMProjectSQL(officedept, pk_org, applyyear));
                        BaseDAO dao = new BaseDAO();
                        try {
                            Map<String, Object> o = (Map<String, Object> )dao.executeQuery(sql.toString(), new MapProcessor());
                            if (o != null && !o.isEmpty()){
                                bvo.setAttributeValue("name", o.get("name"));
                                bvo.setAttributeValue("applyno", o.get("hopbillcode"));
                                bvo.setAttributeValue("spec", o.get("spec"));
                                bvo.setAttributeValue("ks", o.get("pldycbks"));
                                bvo.setAttributeValue("price", o.get("price"));
                                bvo.setAttributeValue("nnum", o.get("nnum"));
                                bvo.setAttributeValue("norigtaxmny", o.get("money"));
                                bvo.setAttributeValue("rowno", rowno);
                            }else {
                                Object orgName = dao.executeQuery("select name from org_orgs where pk_org  = '" + pk_org + "' ", new ColumnProcessor());
                                Object deptName = dao.executeQuery("select name from org_dept where pk_dept  = '" + officedept + "' ", new ColumnProcessor());
                                Object fourXMName = dao.executeQuery("select name from HRPBM_SJXMH where pk_sjxm  = '" + vbdef1 + "' ", new ColumnProcessor());
                                ExceptionUtils.wrappBusinessException("组织:【"+orgName+"】,部门:【"+deptName+"】,年度:【"+applyyear+"】,采购四级项目:【"+fourXMName+"】,已关联！");
                            }
                            rowno += 10;
                        } catch (DAOException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

            }
        }

    }

}